// -----------------------------------------------------------------------------
// M A R I T I M E   R E S E A R C H   I N S T I T U T E   N E T H E R L A N D S
// -----------------------------------------------------------------------------
// Copyright (C) September 2, 2009 MARIN - All rights reserved - http://www.marin.nl
// -----------------------------------------------------------------------------
// Program  : mermaid
// Module   : fws
// File     : ShipGeometry.h
// -----------------------------------------------------------------------------

#ifndef SHIPGEOMETRY_H
#define	SHIPGEOMETRY_H

#include <string>
#include "Geometry.h"
#include "Panels.h"

// -----------------------------------------------------------------------------
// class ShipGeometry
// -----------------------------------------------------------------------------
/// contains panels from msh file
// -----------------------------------------------------------------------------

class ShipGeometry : public Geometry
{

    typedef Geometry super;

public:

    struct ExtendedPanel
    {
        std::vector<mml::Vector3d> vertices;
        mml::Vector3d centroid;
        mml::Vector3d normal;
        double area;
        ExtendedPanel() : vertices(), centroid(), normal(), area(0)
        {
        }
    };

    ShipGeometry();

    virtual ~ShipGeometry();

    bool read(std::string const& fileName);

    std::string getName() const;

    int getNumberOfPanels() const;

    const xxship::Panels& getAppPanels() const;

    const xxship::Panels& getShipPanels() const;

    const xxship::Panels& getEarthPanels() const;

    void getExtendedPanels(std::vector<ShipGeometry::ExtendedPanel> *a_pPanels) const;

    double getBeam() const;

    double getHeight() const;

    double getLPP() const;

    double getDrafAft() const;

    double getDraftFore() const;

    void setPositionOrientation(const mml::Vector3d& xyz, const mml::Vector3d& orientation);

    void setPositionAttitude(const mml::Vector3d& position, const mml::Matrix3d& attitude);

    void getHorizontalBoundingBox(double* pXmin, double* pYmin, double* pXmax, double* pYmax) const;

    bool isOriginApp() const;

    void setOriginApp(bool yes);

private:

    xxship::Panels m_appPanels;     ///< panels in ship coordinates (origin: APP)
    xxship::Panels m_shipPanels;    ///< panels in ship coordinates (origin: amidships at water level)
    xxship::Panels m_earthPanels;   ///< panels in earth coordinates
    std::string    m_name;          ///< name of ship
    double         m_beam;          ///< [m]  beam (maximum width) at waterline (aka B)
    double         m_height;        ///< [m]  max height(deck to keel) amidships (aka H)
    double         m_lpp;           ///< [m]  length between particulars (APP and FPP) (aka LPP)
    double         m_draftAft;      ///< [m]  distance of keel to waterline aft as designed
    double         m_draftFore;     ///< [m]  distance of keel to waterline fore as designed
    bool           m_originApp;     ///< earth coordinates wrt app (or amidships) ?

    void translateAmidships();

    ShipGeometry(const ShipGeometry& orig);
    ShipGeometry & operator=(const ShipGeometry& orig);

};

#endif // SHIPGEOMETRY_H

